From 8aaf870611964a738533c7300e0858e293f5f23a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 3 Mar 2009 11:52:44 +0000 Subject: [PATCH] txt: Xen per-domain S3 integrity config This patch adds a per-domain flag to specify whether a domain will be S3 integrity protected when Xen is launched using tboot/TXT. The tools now support an integer domain configuration parameter called 's3_integrity', which defaults to 1, to enable S3 integrity protection. The struct arch_domain structure has been extended to have an 's3_integrity' field that represents this setting. Signed-off-by: Shane Wang Signed-off-by: Joseph Cihula --- tools/python/xen/xend/XendConfig.py | 1 + tools/python/xen/xend/XendDomainInfo.py | 5 ++++- tools/python/xen/xm/create.py | 10 ++++++++++ tools/python/xen/xm/xenapi_create.py | 4 ++++ xen/arch/x86/domain.c | 2 ++ xen/arch/x86/setup.c | 4 ++-- xen/common/domctl.c | 5 ++++- xen/include/asm-x86/domain.h | 2 ++ xen/include/public/domctl.h | 11 +++++++---- xen/include/xen/sched.h | 16 ++++++++++------ 10 files changed, 46 insertions(+), 14 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 4ab49f390f..f62cd856a1 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -216,6 +216,7 @@ XENAPI_CFG_TYPES = { 'cpuid_check' : dict, 'machine_address_size': int, 'suppress_spurious_page_faults': bool0, + 's3_integrity' : int, } # List of legacy configuration keys that have no equivalent in the diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 6189b89f1d..9a217caa68 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2212,12 +2212,15 @@ class XendDomainInfo: if security.has_authorization(ssidref) == False: raise VmError("VM is not authorized to run.") + s3_integrity = self.info['s3_integrity'] + flags = (int(hvm) << 0) | (int(hap) << 1) | (int(s3_integrity) << 2) + try: self.domid = xc.domain_create( domid = 0, ssidref = ssidref, handle = uuid.fromString(self.info['uuid']), - flags = (int(hvm) << 0) | (int(hap) << 1), + flags = flags, target = self.info.target()) except Exception, e: # may get here if due to ACM the operation is not permitted diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index ebff92b749..3b4da70451 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -579,6 +579,11 @@ gopts.var('hap', val='HAP', use="""Hap status (0=hap is disabled; 1=hap is enabled.""") +gopts.var('s3_integrity', val='TBOOT_MEMORY_PROTECT', + fn=set_int, default=1, + use="""Should domain memory integrity be verified during S3? + (0=protection is disabled; 1=protection is enabled.""") + gopts.var('cpuid', val="IN[,SIN]:eax=EAX,ebx=EBX,ecx=ECX,edx=EDX", fn=append_value, default=[], use="""Cpuid description.""") @@ -832,6 +837,10 @@ def configure_security(config, vals): elif num > 1: err("VM config error: Multiple access_control definitions!") +def configure_mem_prot(config_image, vals): + """Create the config for S3 memory integrity verification under tboot. + """ + config_image.append(['s3_integrity', vals.s3_integrity]) def configure_vtpm(config_devs, vals): """Create the config for virtual TPM interfaces. @@ -964,6 +973,7 @@ def make_config(vals): else: config.append(['bootloader_args', '-q']) config.append(['image', config_image]) + configure_mem_prot(config, vals); config_devs = [] configure_disks(config_devs, vals) diff --git a/tools/python/xen/xm/xenapi_create.py b/tools/python/xen/xm/xenapi_create.py index 74a534f58c..5c6333ccb4 100644 --- a/tools/python/xen/xm/xenapi_create.py +++ b/tools/python/xen/xm/xenapi_create.py @@ -269,6 +269,8 @@ class xenapi_create: vm.attributes["is_a_template"].value == 'true', "auto_power_on": vm.attributes["auto_power_on"].value == 'true', + "s3_integrity": + vm.attributes["s3_integrity"].value, "memory_static_max": get_child_node_attribute(vm, "memory", "static_max"), "memory_static_min": @@ -650,6 +652,8 @@ class sxp2xml: = str(get_child_by_name(config, "vcpus", 1)) vm.attributes["vcpus_at_startup"] \ = str(get_child_by_name(config, "vcpus", 1)) + vm.attributes["s3_integrity"] \ + = str(get_child_by_name(config, "s3_integrity", 0)) sec_data = get_child_by_name(config, "security") if sec_data: diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 5c89eba7ab..4d5cc9d75b 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -386,6 +386,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags) hvm_funcs.hap_supported && (domcr_flags & DOMCRF_hap); + d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity); + INIT_LIST_HEAD(&d->arch.pdev_list); d->arch.relmem = RELMEM_not_started; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index be86447c54..8b9427878e 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -97,6 +97,7 @@ int early_boot = 1; cpumask_t cpu_present_map; unsigned long xen_phys_start; +unsigned long allocator_bitmap_end; #ifdef CONFIG_X86_32 /* Limits of Xen heap, used to initialise the allocator. */ @@ -418,7 +419,6 @@ void __init __start_xen(unsigned long mbi_p) multiboot_info_t *mbi = __va(mbi_p); module_t *mod = (module_t *)__va(mbi->mods_addr); unsigned long nr_pages, modules_length, modules_headroom; - unsigned long allocator_bitmap_end; int i, e820_warn = 0, bytes = 0; struct ns16550_defaults ns16550 = { .data_bits = 8, @@ -990,7 +990,7 @@ void __init __start_xen(unsigned long mbi_p) panic("Could not protect TXT memory regions\n"); /* Create initial domain 0. */ - dom0 = domain_create(0, 0, DOM0_SSIDREF); + dom0 = domain_create(0, DOMCRF_s3_integrity, DOM0_SSIDREF); if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) ) panic("Error creating domain 0\n"); diff --git a/xen/common/domctl.c b/xen/common/domctl.c index f4787b22e3..a693dd7ca4 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -339,7 +339,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) ret = -EINVAL; if ( supervisor_mode_kernel || (op->u.createdomain.flags & - ~(XEN_DOMCTL_CDF_hvm_guest | XEN_DOMCTL_CDF_hap)) ) + ~(XEN_DOMCTL_CDF_hvm_guest | XEN_DOMCTL_CDF_hap | + XEN_DOMCTL_CDF_s3_integrity)) ) break; dom = op->domain; @@ -371,6 +372,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) domcr_flags |= DOMCRF_hvm; if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_hap ) domcr_flags |= DOMCRF_hap; + if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_s3_integrity ) + domcr_flags |= DOMCRF_s3_integrity; ret = -ENOMEM; d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index f1ea4914a7..8fc833a2b9 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -221,6 +221,8 @@ struct arch_domain unsigned int hv_compat_vstart; #endif + bool_t s3_integrity; + /* I/O-port admin-specified access capabilities. */ struct rangeset *ioport_caps; uint32_t pci_cf8; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index c2845e12f3..d6e47cd0e6 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -51,11 +51,14 @@ struct xen_domctl_createdomain { uint32_t ssidref; xen_domain_handle_t handle; /* Is this an HVM guest (as opposed to a PV guest)? */ -#define _XEN_DOMCTL_CDF_hvm_guest 0 -#define XEN_DOMCTL_CDF_hvm_guest (1U<<_XEN_DOMCTL_CDF_hvm_guest) +#define _XEN_DOMCTL_CDF_hvm_guest 0 +#define XEN_DOMCTL_CDF_hvm_guest (1U<<_XEN_DOMCTL_CDF_hvm_guest) /* Use hardware-assisted paging if available? */ -#define _XEN_DOMCTL_CDF_hap 1 -#define XEN_DOMCTL_CDF_hap (1U<<_XEN_DOMCTL_CDF_hap) +#define _XEN_DOMCTL_CDF_hap 1 +#define XEN_DOMCTL_CDF_hap (1U<<_XEN_DOMCTL_CDF_hap) + /* Should domain memory integrity be verifed by tboot during Sx? */ +#define _XEN_DOMCTL_CDF_s3_integrity 2 +#define XEN_DOMCTL_CDF_s3_integrity (1U<<_XEN_DOMCTL_CDF_s3_integrity) uint32_t flags; }; typedef struct xen_domctl_createdomain xen_domctl_createdomain_t; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 24a75552d0..f859849da6 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -341,14 +341,18 @@ static inline struct domain *get_current_domain(void) struct domain *domain_create( domid_t domid, unsigned int domcr_flags, ssidref_t ssidref); /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */ -#define _DOMCRF_hvm 0 -#define DOMCRF_hvm (1U<<_DOMCRF_hvm) +#define _DOMCRF_hvm 0 +#define DOMCRF_hvm (1U<<_DOMCRF_hvm) /* DOMCRF_hap: Create a domain with hardware-assisted paging. */ -#define _DOMCRF_hap 1 -#define DOMCRF_hap (1U<<_DOMCRF_hap) +#define _DOMCRF_hap 1 +#define DOMCRF_hap (1U<<_DOMCRF_hap) + /* DOMCRF_s3_integrity: Create a domain with tboot memory integrity protection + by tboot */ +#define _DOMCRF_s3_integrity 2 +#define DOMCRF_s3_integrity (1U<<_DOMCRF_s3_integrity) /* DOMCRF_dummy: Create a dummy domain (not scheduled; not on domain list) */ -#define _DOMCRF_dummy 2 -#define DOMCRF_dummy (1U<<_DOMCRF_dummy) +#define _DOMCRF_dummy 3 +#define DOMCRF_dummy (1U<<_DOMCRF_dummy) /* * rcu_lock_domain_by_id() is more efficient than get_domain_by_id(). -- 2.30.2